% Test script for ImprovedGeneticAlgorithm.m (for MINIMIZATION)

clear;
clc;
close all;

fprintf('--- Starting Improved Genetic Algorithm Test Case (MINIMIZATION) ---\n');

% --- 1. Define Inputs ---
DSM=zeros(17,17);
DSM(1,3)=1; DSM(2,3)=1; DSM(3,4)=1; DSM(3,5)=1; DSM(3,6)=1;
DSM(4,3)=1; DSM(4,9)=1; DSM(5,3)=1; DSM(5,14)=1; DSM(6,3)=1;
DSM(6,12)=1; DSM(7,6)=1; DSM(8,4)=1; DSM(9,13)=1; DSM(10,5)=1;
DSM(11,5)=1; DSM(12,16)=1; DSM(13,8)=1; DSM(14,15)=1;
DSM(15,10)=1; DSM(15,11)=1; DSM(16,7)=1; DSM(17,5)=1;

params.M = size(DSM, 1);
params.PopulationSize = 50; % Slightly larger
params.MaxGenerations = 50; % Slightly more generations
params.EliteSize = 3;
params.CrossoverRate = 0.85;
params.MutationK1 = 0.15; 
params.MutationK2 = 0.08; 
params.ClusterSimilarityThresholdA = 0.2;
params.VNS_MaxNeighborhoods = 2; 
params.AprioriMinSupport = 2; % Lower for smaller pop/fewer generations
params.AprioriFrequencyTheta = 5; % More frequent check
params.TournamentSize = 2;

fprintf('Parameters set:\n');
disp(params);

% --- 2. Add Error Handling ---
dbstop if error
% dbstop if warning % Uncomment to catch specific linter warnings

% --- 3. Run the Algorithm ---
fprintf('\nRunning ImprovedGeneticAlgorithm...\n');
startTime = tic;

% Run GA. It returns GA's internal fitness (which is -objective_value)
[bestSolCell, bestInternalFitnessFromGA, fitnessHistoryInternalFromGA] = ImprovedGeneticAlgorithm(DSM, params);

elapsedTime = toc(startTime);
fprintf('Algorithm finished in %.2f seconds.\n', elapsedTime);

% --- 4. Display Results (Convert back to true minimized objective) ---
fprintf('\n--- Results ---\n');

if ~isempty(bestSolCell) && iscell(bestSolCell) && ~isempty(bestSolCell{1})
     % bestInternalFitnessFromGA is the maximized (-objective). Negate it for true minimum.
     trueBestMinimumObjective = -bestInternalFitnessFromGA; 
     
     fprintf('True Best Minimum Objective Found: %.4f\n', trueBestMinimumObjective);
     fprintf('Best Solution Structure (Chromosome Matrix - %d Modules):\n', size(bestSolCell{1}, 1));
     disp(bestSolCell{1}); 
 
     fprintf('Module Assignments (Element -> Module Index):\n');
     [module_indices, ~] = find(bestSolCell{1}'); 
     if length(module_indices) == params.M
          disp(module_indices'); 
     else
          fprintf('Could not display module assignments easily.\n');
     end
 
else 
     trueBestMinimumObjective = -bestInternalFitnessFromGA; % Still negate if it's a valid number
     fprintf('True Best Minimum Objective (if any from run): %.4f\n', trueBestMinimumObjective);
     fprintf('Best Solution: Algorithm did not return a valid solution structure.\n');
end

% --- 5. Plot Fitness History (Plot the true minimized objective) ---
if ~isempty(fitnessHistoryInternalFromGA) && length(fitnessHistoryInternalFromGA) == params.MaxGenerations
    figure; 
    % fitnessHistoryInternalFromGA contains maximized (-objective). Negate for true minimum.
    trueMinObjectiveHistory = -fitnessHistoryInternalFromGA; 
    
    plot(1:params.MaxGenerations, trueMinObjectiveHistory, '-o', 'LineWidth', 1.5);
    title('True Minimum Objective History per Generation');
    xlabel('Generation');
    ylabel('Best Minimum Objective Value');
    grid on;
    fprintf('\nTrue minimum objective history plot generated.\n');
else
    fprintf('\nFitness history was not generated or has incorrect length.\n');
end

fprintf('\n--- Test Case Finished ---\n');

% dbclear if error
% dbclear if warning